<?php
/**
 * 这是一个用数据库保存会话的示例，而且用数据库保存会话是必须的
 * 如果需要使用会话，可以直接包含此文件
 *
 * 这个类需要改进，在各个函数中应当加入执行结果的判定后再返回值
 *
 * User: ford
 * Date: 15-7-28
 * Time: 下午2:22
 */
//定义一个全局变量来保存连接，因为每个函数都要用
$sdbc = null;

/**
 * 打开会话时调用的函数不需要参数
 * 用它来打开数据库连接
 * @return bool
 */
function open_session() {
	global $sdbc;

	$sdbc = mysqli_connect('localhost', 'root', 'al8840dd', 'test') or die('数据库连接失败！');

	return true;
}

/**
 * 关闭会话时调用的函数
 * 不需要参数，用来关闭数据库连接
 * 它返回关闭状态
 * @return bool
 */
function close_session() {
	global $sdbc;

	return mysqli_close($sdbc);
}

/**
 * 读取会话时调用的函数
 * 它需要一个参数，即会话ID
 * @param $session_id
 * @return string
 */
function read_session($session_id) {
	global $sdbc;

	//查询会话数据
	$q = sprintf('SELECT data FROM sessions WHERE id="%s"', mysqli_real_escape_string($sdbc, $session_id));
	$r = mysqli_query($sdbc, $q);

	//返回查询结果，如果没有数据，则返回空字符串
	if(mysqli_num_rows($r) == 1) {
		list($data) = mysqli_fetch_array($r, MYSQLI_NUM);

		return $data;
	} else {
		return '';
	}

}

/**
 * 存储会话内容执行的函数
 * 需要两个参数，要写入的会话ID和会话内容，
 * 注意，这里使用了REPLACE INTO语句，它取代了INSERT和UPDATE，它的功能是在ID不存在是创建一条新记录，如果存在就更新它，节省了代码
 * @param $session_id
 * @param $data
 * @return bool
 */
function write_session($session_id, $data) {
	global $sdbc;

	//将会话内容存储在数据库中
	$q = sprintf('REPLACE INTO sessions(id, data) VALUES ("%s", "%s")', mysqli_real_escape_string($sdbc, $session_id), mysqli_real_escape_string($sdbc, $data));
	$r = mysqli_query($sdbc, $q);
	if(mysqli_fetch_row($r) == 1) {
		return true;
	} else {
		return false;
	}

}

/**
 * 销毁会话执行的函数
 * 需要一个参数，会话ID
 * 同时也清空$_SESSION数组
 * @param $session_id
 * @return bool
 */
function destroy_session($session_id) {
	global $sdbc;

	//删除会话记录
	$q = sprintf('DELETE FROM sessions WHERE id="%s"', mysqli_real_escape_string($sdbc, $session_id));
	$r = mysqli_query($sdbc, $q);

	//清空会话数组
	$_SESSION = array();

	return true;
}

/**
 * 删除旧会话时执行的函数
 * 需要一个整型参数，单位是秒，表示现在往前XX秒之前的会话
 * @param $expire
 * @return bool
 */
function clean_session($expire) {
	global $sdbc;

	//删除从现在往$expire秒之前的会话数据
	$q = sprintf('DELETE FROM sessions WHERE DATE_ADD(last_accesed, INTERVAL %d SECOND) < NOW()', (int)$expire);
	$r = mysqli_query($sdbc, $q);

	return true;
}

//声明会话控制函数
session_set_save_handler('open_session', 'close_session', 'read_session', 'write_session', 'destroy_session', 'clean_session');

session_start();